﻿//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2020 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------

using System;
using System.IO;
using Core;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;

namespace UnityGameFramework.Editor.ResourceTools
{

    /// <summary>
    /// 资源生成器。
    /// </summary>
    internal sealed class ResourceBuilder : EditorWindow
    {
        private ResourceBuilderController m_Controller;
        private bool m_OrderBuildResources;
        private bool m_AutoPack_Update_Upload2Oss;
        private int m_BuildEventHandlerTypeNameIndex;
        private Vector2 m_Scroll_ViewPoint = Vector2.zero;

        [MenuItem("ThirdParty Tools/Game Framework/Resource Tools/Resource Builder", false, 41)]
        private static void Open()
        {
            ResourceBuilder window = GetWindow<ResourceBuilder>("Resource Builder", true);
#if UNITY_2019_3_OR_NEWER
            window.minSize = new Vector2(800f, 645f);
#else
            window.minSize = new Vector2(800f, 605f);
#endif
        }

        private void OnEnable()
        {
            m_Controller = new ResourceBuilderController();
            m_Controller.OnLoadingResource += OnLoadingResource;
            m_Controller.OnLoadingAsset += OnLoadingAsset;
            m_Controller.OnLoadCompleted += OnLoadCompleted;
            m_Controller.OnAnalyzingAsset += OnAnalyzingAsset;
            m_Controller.OnAnalyzeCompleted += OnAnalyzeCompleted;
            m_Controller.ProcessingAssetBundle += OnProcessingAssetBundle;
            m_Controller.ProcessingBinary += OnProcessingBinary;
            m_Controller.ProcessResourceComplete += OnProcessResourceComplete;
            m_Controller.BuildResourceError += OnBuildResourceError;

            m_OrderBuildResources = false;
            m_AutoPack_Update_Upload2Oss = false;

            if (m_Controller.Load())
            {
                Debug.Log("Load configuration success.");
                m_BuildEventHandlerTypeNameIndex = 0;
                string[] buildEventHandlerTypeNames = m_Controller.GetBuildEventHandlerTypeNames();
                for (int i = 0; i < buildEventHandlerTypeNames.Length; i++)
                {
                    if (m_Controller.BuildEventHandlerTypeName == buildEventHandlerTypeNames[i])
                    {
                        m_BuildEventHandlerTypeNameIndex = i;
                        break;
                    }
                }

                m_Controller.RefreshBuildEventHandler();
            }
            else
            {
                Debug.LogWarning("Load configuration failure.");
            }
        }

        private void Update()
        {
            if (m_OrderBuildResources)
            {
                m_OrderBuildResources = false;
                BuildResources();
            }

            if (m_AutoPack_Update_Upload2Oss)
            {
                m_AutoPack_Update_Upload2Oss = false;
                // AutoPackForUpdateNUpload2OssMode();
            }
        }

        private void OnGUI()
        {
            m_Scroll_ViewPoint = EditorGUILayout.BeginScrollView(m_Scroll_ViewPoint, GUILayout.Width(position.width), GUILayout.Height(position.height));
            EditorGUILayout.BeginVertical();
            {
                GUILayout.Space(5f);
                EditorGUILayout.LabelField("Environment Information", EditorStyles.boldLabel);
                EditorGUILayout.BeginVertical("box");
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Product Name", GUILayout.Width(160f));
                        EditorGUILayout.LabelField(m_Controller.ProductName);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Company Name", GUILayout.Width(160f));
                        EditorGUILayout.LabelField(m_Controller.CompanyName);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Game Identifier", GUILayout.Width(160f));
                        EditorGUILayout.LabelField(m_Controller.GameIdentifier);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Game Framework Version", GUILayout.Width(160f));
                        EditorGUILayout.LabelField(m_Controller.GameFrameworkVersion);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Unity Version", GUILayout.Width(160f));
                        EditorGUILayout.LabelField(m_Controller.UnityVersion);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Applicable Game Version", GUILayout.Width(160f));
                        EditorGUILayout.LabelField(m_Controller.ApplicableGameVersion);
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndVertical();
                GUILayout.Space(5f);
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.BeginVertical();
                    {
                        EditorGUILayout.LabelField("Platforms", EditorStyles.boldLabel);
                        EditorGUILayout.BeginHorizontal("box");
                        {
                            EditorGUILayout.BeginVertical();
                            {
                                DrawPlatform(Platform.Windows, "Windows");
                                DrawPlatform(Platform.Windows64, "Windows x64");
                                DrawPlatform(Platform.MacOS, "macOS");
                                DrawPlatform(Platform.Linux, "Linux");
                                DrawPlatform(Platform.IOS, "iOS");
                                DrawPlatform(Platform.Android, "Android");
                            }
                            EditorGUILayout.EndVertical();
                            EditorGUILayout.BeginVertical();
                            {
                                DrawPlatform(Platform.WindowsStore, "Windows Store");
                                DrawPlatform(Platform.WebGL, "WebGL");
                            }
                            EditorGUILayout.EndVertical();
                        }
                        EditorGUILayout.EndHorizontal();
                        EditorGUILayout.BeginVertical();
                        {
                            m_Controller.ZipSelected = EditorGUILayout.ToggleLeft("Zip All Resources", m_Controller.ZipSelected);
                        }
                        EditorGUILayout.EndVertical();
                    }
                    EditorGUILayout.EndVertical();
                    EditorGUILayout.BeginVertical();
                    {
                        EditorGUILayout.LabelField("AssetBundle Options", EditorStyles.boldLabel);
                        EditorGUILayout.BeginVertical("box");
                        {
                            bool uncompressedAssetBundleSelected = EditorGUILayout.ToggleLeft("Uncompressed AssetBundle", m_Controller.UncompressedAssetBundleSelected);
                            if (m_Controller.UncompressedAssetBundleSelected != uncompressedAssetBundleSelected)
                            {
                                m_Controller.UncompressedAssetBundleSelected = uncompressedAssetBundleSelected;
                                if (m_Controller.UncompressedAssetBundleSelected)
                                {
                                    m_Controller.ChunkBasedCompressionSelected = false;
                                }
                            }

                            bool disableWriteTypeTreeSelected = EditorGUILayout.ToggleLeft("Disable Write TypeTree", m_Controller.DisableWriteTypeTreeSelected);
                            if (m_Controller.DisableWriteTypeTreeSelected != disableWriteTypeTreeSelected)
                            {
                                m_Controller.DisableWriteTypeTreeSelected = disableWriteTypeTreeSelected;
                                if (m_Controller.DisableWriteTypeTreeSelected)
                                {
                                    m_Controller.IgnoreTypeTreeChangesSelected = false;
                                }
                            }

                            m_Controller.DeterministicAssetBundleSelected = EditorGUILayout.ToggleLeft("Deterministic AssetBundle", m_Controller.DeterministicAssetBundleSelected);
                            m_Controller.ForceRebuildAssetBundleSelected = EditorGUILayout.ToggleLeft("Force Rebuild AssetBundle", m_Controller.ForceRebuildAssetBundleSelected);
                            m_Controller.OnlySingleBuildSelected = EditorGUILayout.ToggleLeft("Only Single Build AssetBundle(beta)", m_Controller.OnlySingleBuildSelected);

                            bool ignoreTypeTreeChangesSelected = EditorGUILayout.ToggleLeft("Ignore TypeTree Changes", m_Controller.IgnoreTypeTreeChangesSelected);
                            if (m_Controller.IgnoreTypeTreeChangesSelected != ignoreTypeTreeChangesSelected)
                            {
                                m_Controller.IgnoreTypeTreeChangesSelected = ignoreTypeTreeChangesSelected;
                                if (m_Controller.IgnoreTypeTreeChangesSelected)
                                {
                                    m_Controller.DisableWriteTypeTreeSelected = false;
                                }
                            }

                            EditorGUI.BeginDisabledGroup(true);
                            {
                                m_Controller.AppendHashToAssetBundleNameSelected = EditorGUILayout.ToggleLeft("Append Hash To AssetBundle Name", m_Controller.AppendHashToAssetBundleNameSelected);
                            }
                            EditorGUI.EndDisabledGroup();

                            bool chunkBasedCompressionSelected = EditorGUILayout.ToggleLeft("Chunk Based Compression", m_Controller.ChunkBasedCompressionSelected);
                            if (m_Controller.ChunkBasedCompressionSelected != chunkBasedCompressionSelected)
                            {
                                m_Controller.ChunkBasedCompressionSelected = chunkBasedCompressionSelected;
                                if (m_Controller.ChunkBasedCompressionSelected)
                                {
                                    m_Controller.UncompressedAssetBundleSelected = false;
                                }
                            }
                        }
                        EditorGUILayout.EndVertical();
                    }
                    EditorGUILayout.EndVertical();
                }
                EditorGUILayout.EndHorizontal();
                string compressMessage = string.Empty;
                MessageType compressMessageType = MessageType.None;
                GetCompressMessage(out compressMessage, out compressMessageType);
                EditorGUILayout.HelpBox(compressMessage, compressMessageType);
                GUILayout.Space(5f);
                EditorGUILayout.LabelField("Build", EditorStyles.boldLabel);
                EditorGUILayout.BeginVertical("box");
                {
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Build Event Handler", GUILayout.Width(160f));
                        string[] names = m_Controller.GetBuildEventHandlerTypeNames();
                        int selectedIndex = EditorGUILayout.Popup(m_BuildEventHandlerTypeNameIndex, names);
                        if (selectedIndex != m_BuildEventHandlerTypeNameIndex)
                        {
                            m_BuildEventHandlerTypeNameIndex = selectedIndex;
                            m_Controller.BuildEventHandlerTypeName = selectedIndex <= 0 ? string.Empty : names[selectedIndex];
                            if (m_Controller.RefreshBuildEventHandler())
                            {
                                Debug.Log("Set build event success.");
                            }
                            else
                            {
                                Debug.LogWarning("Set build event failure.");
                            }
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Internal Game Version", GUILayout.Width(160f));
                        m_Controller.InternalGameVersion = EditorGUILayout.IntField(m_Controller.InternalGameVersion);
                        EditorGUILayout.LabelField("Internal Resource Version", GUILayout.Width(160f));
                        m_Controller.InternalResourceVersion = EditorGUILayout.IntField(m_Controller.InternalResourceVersion);
                        EditorGUI.BeginDisabledGroup(!m_Controller.OssProdMode);
                        EditorGUILayout.LabelField("OssProdMode", GUILayout.Width(100f));
                        EditorGUI.EndDisabledGroup();
                        m_Controller.OssProdMode = EditorGUILayout.ToggleLeft("", m_Controller.OssProdMode, GUILayout.Width(30f));
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Resource Version", GUILayout.Width(160f));
                        GUILayout.Label(Utils.Text.Format("{0} ({1})", m_Controller.ApplicableGameVersion, m_Controller.InternalResourceVersion.ToString()));
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Output Directory", GUILayout.Width(160f));
                        m_Controller.OutputDirectory = EditorGUILayout.TextField(m_Controller.OutputDirectory);
                        if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                        {
                            BrowseOutputDirectory();
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Working Path", GUILayout.Width(160f));
                        GUILayout.Label(m_Controller.WorkingPath);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUI.BeginDisabledGroup(!m_Controller.OutputFullSelected);
                        EditorGUILayout.LabelField("Output Full Path", GUILayout.Width(160f));
                        GUILayout.Label(m_Controller.OutputFullPath);
                        EditorGUI.EndDisabledGroup();
                        m_Controller.OutputFullSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputFullSelected, GUILayout.Width(70f));
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackageSelected);
                        EditorGUILayout.LabelField("Output Package Path", GUILayout.Width(160f));
                        GUILayout.Label(m_Controller.OutputPackagePath);
                        EditorGUI.EndDisabledGroup();
                        m_Controller.OutputPackageSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackageSelected, GUILayout.Width(70f));
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUI.BeginDisabledGroup(!m_Controller.OutputPackedSelected);
                        EditorGUILayout.LabelField("Output Packed Path", GUILayout.Width(160f));
                        GUILayout.Label(m_Controller.OutputPackedPath);
                        EditorGUI.EndDisabledGroup();
                        m_Controller.OutputPackedSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPackedSelected, GUILayout.Width(70f));
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUI.BeginDisabledGroup(!m_Controller.OutputPureSelected);
                        EditorGUILayout.LabelField("Output Pure Path", GUILayout.Width(160f));
                        GUILayout.Label(m_Controller.OutputPurePath);
                        EditorGUI.EndDisabledGroup();
                        m_Controller.OutputPureSelected = EditorGUILayout.ToggleLeft("Generate", m_Controller.OutputPureSelected, GUILayout.Width(70f));
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("Build Report Path", GUILayout.Width(160f));
                        GUILayout.Label(m_Controller.BuildReportPath);
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("SVN Path", GUILayout.Width(160f));
                        m_Controller.SVNPath = EditorGUILayout.TextField(m_Controller.SVNPath);
                        if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                        {
                            BrowseSVNPath();
                        }
                    }
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                    {
                        EditorGUILayout.LabelField("IOS App Url", GUILayout.Width(160f));
                        m_Controller.IOSAppUrl = EditorGUILayout.TextField(m_Controller.IOSAppUrl);
                        //}
                        //EditorGUILayout.EndHorizontal();
                        //EditorGUILayout.BeginHorizontal();
                        //{
                        EditorGUILayout.LabelField("Android App Url", GUILayout.Width(160f));
                        m_Controller.AndroidAppUrl = EditorGUILayout.TextField(m_Controller.AndroidAppUrl);
                    }
                    EditorGUILayout.EndHorizontal();
                }
                EditorGUILayout.EndVertical();
                string buildMessage = string.Empty;
                MessageType buildMessageType = MessageType.None;
                GetBuildMessage(out buildMessage, out buildMessageType);
                EditorGUILayout.HelpBox(buildMessage, buildMessageType);
                GUILayout.Space(2f);

                SDKSwitch();

                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUI.BeginDisabledGroup(m_Controller.SelectedPlatform == Platform.Undefined || !m_Controller.IsValidOutputDirectory);
                    {
                        if (GUILayout.Button("Start Build Resources"))
                        {
                            m_OrderBuildResources = true;
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                    if (GUILayout.Button("Save", GUILayout.Width(100f)))
                    {
                        SaveConfiguration();
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("CopyPackage2StreamingAssets"))
                    {
                        CopyPackage2StreamingAssets();
                    }
                    if (GUILayout.Button("CopyPacked2StreamingAssets"))
                    {
                        CopyPacked2StreamingAssets();
                    }
                    if (GUILayout.Button("CopyPure2StreamingAssets"))
                    {
                        CopyPure2StreamingAssets();
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("CopyFull2SVNPath"))
                    {
                        CopyFull2SVNPath();
                    }
                    if (GUILayout.Button("Upload2Oss"))
                    {

                        log.err("Upload2Oss");
                        // m_Controller.Upload2Oss();
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("检测资源冗余"))
                    {
                        m_Controller.CheckRedundancy();
                    }
                    if (GUILayout.Button("生成Bundle资源分布表"))
                    {
                        m_Controller.CheckBundleDistribute();
                    }
                    if (GUILayout.Button("Test"))
                    {
                        //ShaderVariantsCollect.GenShaderVariant();
                        m_Controller.Test();
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.BeginHorizontal();
                {
                    m_Controller.SdkChannel = (ResourceBuilderController.ESdkChannel)EditorGUILayout.EnumPopup(m_Controller.SdkChannel);
                    if (GUILayout.Button("切换安卓渠道SDK文件"))
                    {
                        SwitchChanneleFile();
                    }
                }
                EditorGUILayout.EndHorizontal();
                GUILayout.Space(10f);
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUI.BeginDisabledGroup(m_Controller.SelectedPlatform == Platform.Undefined || !m_Controller.IsValidOutputDirectory);
                    {
                        if (GUILayout.Button("安卓一键打包\n\nUpdate - DevServerReq - Packed2Streaming - CopyFull - Upload2Oss", GUILayout.Height(50)))
                        {
                            m_AutoPack_Update_Upload2Oss = true;
                        }
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndScrollView();
        }

        private void SwitchChanneleFile()
        {
            var path = Application.dataPath + "/Plugins/Android/";
            var sdkPath = Application.dataPath + "/../Channels/" + m_Controller.SdkChannel.ToString() + "/Plugins/Android/";
            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }
            Directory.CreateDirectory(path);
            CopyDirectory(sdkPath, path);
            m_Controller.WriteVersionTxt();
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
        /// <summary>
        /// 文件夹下所有内容copy
        /// </summary>
        /// <param name="SourcePath">要Copy的文件夹</param>
        /// <param name="DestinationPath">要复制到哪个地方</param>
        /// <param name="overwriteexisting">是否覆盖</param>
        /// <returns></returns>
        private static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting = true)
        {
            bool ret = false;
            try
            {
                SourcePath = SourcePath.EndsWith(@"\") ? SourcePath : SourcePath + @"\";
                DestinationPath = DestinationPath.EndsWith(@"\") ? DestinationPath : DestinationPath + @"\";

                if (Directory.Exists(SourcePath))
                {
                    if (Directory.Exists(DestinationPath) == false)
                        Directory.CreateDirectory(DestinationPath);

                    foreach (string fls in Directory.GetFiles(SourcePath))
                    {
                        FileInfo flinfo = new FileInfo(fls);
                        flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
                    }
                    foreach (string drs in Directory.GetDirectories(SourcePath))
                    {
                        DirectoryInfo drinfo = new DirectoryInfo(drs);
                        if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false)
                            ret = false;
                    }
                }
                ret = true;
            }
            catch (Exception)
            {
                ret = false;
            }
            return ret;
        }
        private void BrowseOutputDirectory()
        {
            string directory = EditorUtility.OpenFolderPanel("Select Output Directory", m_Controller.OutputDirectory, string.Empty);
            if (!string.IsNullOrEmpty(directory))
            {
                m_Controller.OutputDirectory = directory;
            }
        }

        private void BrowseSVNPath()
        {
            string directory = EditorUtility.OpenFolderPanel("Select SVN Path", m_Controller.SVNPath, string.Empty);
            if (!string.IsNullOrEmpty(directory))
            {
                m_Controller.SVNPath = directory;
            }
        }

        private void GetCompressMessage(out string message, out MessageType messageType)
        {
            if (m_Controller.ZipSelected)
            {
                if (m_Controller.UncompressedAssetBundleSelected)
                {
                    message = "Compresses AssetBundles with ZIP only. It uses more storage but it's faster when loading the AssetBundles.";
                    messageType = MessageType.Info;
                }
                else if (m_Controller.ChunkBasedCompressionSelected)
                {
                    message = "Compresses AssetBundles with both chunk-based compression and ZIP. Recommended when you use 'AssetBundle.LoadFromFile'.";
                    messageType = MessageType.Info;
                }
                else
                {
                    message = "Compresses AssetBundles with both LZMA and ZIP. Not recommended.";
                    messageType = MessageType.Warning;
                }
            }
            else
            {
                if (m_Controller.UncompressedAssetBundleSelected)
                {
                    message = "Doesn't compress AssetBundles at all. Not recommended.";
                    messageType = MessageType.Warning;
                }
                else if (m_Controller.ChunkBasedCompressionSelected)
                {
                    message = "Compresses AssetBundles with chunk-based compression only. Recommended when you use 'AssetBundle.LoadFromFile'.";
                    messageType = MessageType.Info;
                }
                else
                {
                    message = "Compresses AssetBundles with LZMA only. Recommended when you use 'AssetBundle.LoadFromMemory'.";
                    messageType = MessageType.Info;
                }
            }
        }

        private void GetBuildMessage(out string message, out MessageType messageType)
        {
            if (m_Controller.SelectedPlatform == Platform.Undefined)
            {
                message = "Platform undefined.";
                messageType = MessageType.Error;
                return;
            }

            if (!m_Controller.IsValidOutputDirectory)
            {
                message = "Output directory is invalid.";
                messageType = MessageType.Error;
                return;
            }

            message = string.Empty;
            messageType = MessageType.Info;
            if (Directory.Exists(m_Controller.OutputPackagePath))
            {
                message += Utils.Text.Format("{0} will be overwritten.", m_Controller.OutputPackagePath);
                messageType = MessageType.Warning;
            }

            if (Directory.Exists(m_Controller.OutputFullPath))
            {
                if (message.Length > 0)
                {
                    message += " ";
                }

                message += Utils.Text.Format("{0} will be overwritten.", m_Controller.OutputFullPath);
                messageType = MessageType.Warning;
            }

            if (Directory.Exists(m_Controller.OutputPackedPath))
            {
                if (message.Length > 0)
                {
                    message += " ";
                }

                message += Utils.Text.Format("{0} will be overwritten.", m_Controller.OutputPackedPath);
                messageType = MessageType.Warning;
            }

            if (messageType == MessageType.Warning)
            {
                return;
            }

            message = "Ready to build.";
        }

        private void BuildResources()
        {
            if (m_Controller.BuildResources())
            {
                Debug.Log("Build resources success.");
                SaveConfiguration();
            }
            else
            {
                Debug.LogWarning("Build resources failure.");
            }
        }
        //
        // private void AutoPackForUpdateNUpload2OssMode()
        // {
        //     var initSceneArray = StageUtility.GetCurrentStageHandle().FindComponentsOfType<Init>();
        //     if (initSceneArray.Length == 0)
        //     {
        //         Debug.LogError($"Wrong Scene, Please Open Start.unity");
        //         return;
        //     }
        //     var initComponent = initSceneArray[0];
        //     initComponent.ResMode = EResMode.Update;
        //     GameDefine.EResMode = EResMode.Update;
        //     initComponent.TestReqServerMode = true;
        //     GameDefine.TestReqServerMode = true;
        //
        //     if (m_Controller.BuildResources())
        //     {
        //         Debug.Log("Build resources success.");
        //         SaveConfiguration();
        //
        //
        //         Debug.Log("Begin Copy Packed2StreamingAssets");
        //         if (m_Controller.CopyPacked())
        //         {
        //             Debug.Log("Copy Dictionary success.");
        //         }
        //         else
        //         {
        //             Debug.LogWarning("Copy Dictionary failure.");
        //             return;
        //         }
        //
        //
        //         Debug.Log("Begin Copy to SVN");
        //         if (m_Controller.Copy2SVN())
        //         {
        //             Debug.Log("Copy success.");
        //         }
        //         else
        //         {
        //             Debug.LogWarning("Copy failure.");
        //             return;
        //         }
        //
        //
        //         Debug.Log("Begin Upload to Oss");
        //         m_Controller.Upload2Oss();
        //
        //
        //         Debug.Log("Begin Build");
        //         BuildPlayerWindow.ShowBuildPlayerWindow();
        //     }
        //     else
        //     {
        //         Debug.LogWarning("Build resources failure.");
        //     }
        // }

        private void SaveConfiguration()
        {
            if (m_Controller.Save())
            {
                Debug.Log("Save configuration success.");
            }
            else
            {
                Debug.LogWarning("Save configuration failure.");
            }
        }

        private void CopyPackage2StreamingAssets()
        {
            if (m_Controller.CopyPackage())
            {
                Debug.Log("Copy Dictionary success.");
            }
            else
            {
                Debug.LogWarning("Copy Dictionary failure.");
            }
        }

        private void CopyPacked2StreamingAssets()
        {
            if (m_Controller.CopyPacked())
            {
                Debug.Log("Copy Dictionary success.");
            }
            else
            {
                Debug.LogWarning("Copy Dictionary failure.");
            }
        }

        private void CopyPure2StreamingAssets()
        {
            if (m_Controller.CopyPure())
            {
                Debug.Log("Copy Dictionary success.");
            }
            else
            {
                Debug.LogWarning("Copy Dictionary failure.");
            }
        }

        private void CopyFull2SVNPath()
        {
            if (m_Controller.Copy2SVN())
            {
                Debug.Log("Copy success.");
            }
            else
            {
                Debug.LogWarning("Copy failure.");
            }
        }
        private void DrawPlatform(Platform platform, string platformName)
        {
            m_Controller.SelectPlatform(platform, EditorGUILayout.ToggleLeft(platformName, m_Controller.IsPlatformSelected(platform)));
        }

        private void OnLoadingResource(int index, int count)
        {
            EditorUtility.DisplayProgressBar("Loading Resources", Utils.Text.Format("Loading resources, {0}/{1} loaded.", index.ToString(), count.ToString()), (float)index / count);
        }

        private void OnLoadingAsset(int index, int count)
        {
            EditorUtility.DisplayProgressBar("Loading Assets", Utils.Text.Format("Loading assets, {0}/{1} loaded.", index.ToString(), count.ToString()), (float)index / count);
        }

        private void OnLoadCompleted()
        {
            EditorUtility.ClearProgressBar();
        }

        private void OnAnalyzingAsset(int index, int count)
        {
            EditorUtility.DisplayProgressBar("Analyzing Assets", Utils.Text.Format("Analyzing assets, {0}/{1} analyzed.", index.ToString(), count.ToString()), (float)index / count);
        }

        private void OnAnalyzeCompleted()
        {
            EditorUtility.ClearProgressBar();
        }

        private bool OnProcessingAssetBundle(string assetBundleName, float progress)
        {
            if (EditorUtility.DisplayCancelableProgressBar("Processing AssetBundle", Utils.Text.Format("Processing '{0}'...", assetBundleName), progress))
            {
                EditorUtility.ClearProgressBar();
                return true;
            }
            else
            {
                Repaint();
                return false;
            }
        }

        private bool OnProcessingBinary(string binaryName, float progress)
        {
            if (EditorUtility.DisplayCancelableProgressBar("Processing Binary", Utils.Text.Format("Processing '{0}'...", binaryName), progress))
            {
                EditorUtility.ClearProgressBar();
                return true;
            }
            else
            {
                Repaint();
                return false;
            }
        }

        private void OnProcessResourceComplete(Platform platform)
        {
            EditorUtility.ClearProgressBar();
            Debug.Log(Utils.Text.Format("Build resources for '{0}' complete.", platform.ToString()));
        }

        private void OnBuildResourceError(string errorMessage)
        {
            EditorUtility.ClearProgressBar();
            Debug.LogWarning(Utils.Text.Format("Build resources error with error message '{0}'.", errorMessage));
        }

        #region SDK增删逻辑

        /// <summary>
        /// 设置SDK开关标记
        /// </summary>
        private void SDKSwitch()
        {
            EditorGUILayout.BeginVertical("box");
            {
                {//调用具体的SDK UI逻辑
                    SetSDKSwitch();

                }


                GUILayout.Space(8f);
                EditorGUILayout.BeginHorizontal();
                {
                    EditorGUILayout.LabelField("", GUILayout.Width(600f));
                    if (GUILayout.Button("刷新Plugins引用的SDK文件"))
                    {
                        RefreshPluginsSDKFile();
                    }
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
            GUILayout.Space(4f);
        }

        /// <summary>
        /// 增删Plugins下引用的SDK资源
        /// </summary>
        private void RefreshPluginsSDKFile()
        {
            RefreshYDFile();
            RefreshShuShuSDKFile();
            DeletePluginsSDKFile();
            AddTargetPluginsSDKFile();
            m_Controller.WriteVersionTxt();
            AssetDatabase.Refresh();
        }

        private void DeletePluginsSDKFile()
        {
            RefreshReYunFile(true);
            RefreshBilibliFile(true);
            RefreshQuickFile(true);
        }

        private void AddTargetPluginsSDKFile()
        {
            RefreshReYunFile(false);
            RefreshBilibliFile(false);
            RefreshQuickFile(false);
        }

        private void AddSDKFile2Plugins(string path, string skipFileName = null)
        {
            Dispose2Target(path, Application.dataPath + "/Plugins", skipFile: skipFileName);
        }

        private void RemoveSDKFile2Plugins(string path)
        {
            Dispose2Target(path, Application.dataPath + "/Plugins", true);
        }

        private static void Dispose2Target(string oPath, string nPath, bool del = false, string skipFile = null)
        {
            string[] oDirList = Directory.GetDirectories(oPath);
            string[] nDirList = Directory.GetDirectories(nPath);
            foreach (var oDir in oDirList)
            {
                string oFileName = Path.GetFileName(oDir);
                foreach (var nDir in nDirList)
                {
                    string nFileName = Path.GetFileName(nDir);
                    if (nFileName.Equals(oFileName))
                    {
                        Dispose2Target(oPath + "/" + oFileName, nPath + "/" + oFileName, del, skipFile);
                    }
                }
            }

            Debug.LogError($"处理文件夹：{oPath}");
            var oFileList = Directory.GetFiles(oPath);
            var nFileList = Directory.GetFiles(nPath);
            foreach (var oFile in oFileList)
            {
                bool isExists = false;
                string oFileName = Path.GetFileName(oFile);
                if (skipFile != null && skipFile.Contains(oFileName))
                {
                    Debug.LogError($"跳过文件：{oFileName}");
                    continue;
                }
                foreach (var nFile in nFileList)
                {
                    string nFileName = Path.GetFileName(nFile);
                    if (nFileName.Equals(oFileName))
                    {
                        if (del)
                        {
                            Debug.LogError($"删除文件：{nFileName}");
                            File.Delete(nFile);
                        }
                        else
                        {
                            isExists = true;
                            break;
                        }
                    }
                }
                if (isExists == false)
                {
                    if (del == false)
                    {
                        Debug.LogError($"拷贝文件：{oFileName}");
                        string dest = Path.Combine(nPath, oFileName);
                        File.Copy(oFile, dest);
                    }
                }
            }
        }

        #region 易盾
        private bool YD_Switch_Tag;
        private string mYD_SDK_Path;

        private string YD_SDK_Path
        {
            get {
                if (string.IsNullOrEmpty(mYD_SDK_Path))
                {
                    mYD_SDK_Path = Application.dataPath + "/../SDK/易盾/Plugins";
                }
                return mYD_SDK_Path;
            }
            set { mYD_SDK_Path = value; }
        }

        private bool m_bilibili_tag;
        private string m_bilibili_path;
        private string bilibili_path
        {
            get
            {
                return Application.dataPath + "/../SDK/bilibili/Plugins";
            }
            set { m_bilibili_path = value; }
        }
        private bool m_shushu_tag;
        private string m_shushu_path;
        private string shushu_path
        {
            get
            {
                if (string.IsNullOrEmpty(m_shushu_path))
                {
                    m_shushu_path = Application.dataPath + "/../SDK/ShuShuSDK";
                }
                return m_shushu_path;
            }
            set { m_shushu_path = value; }
        }

        private bool m_reyun_tag;
        private string m_reyun_path;
        private string reyun_path
        {
            get
            {
                if (m_reyun_path == null)
                {
                    m_reyun_path = Application.dataPath + "/../SDK/ReYun/Plugins";
                }
                return m_reyun_path;
            }
            set { m_reyun_path = value; }
        }

        private bool m_quick_tag;
        private string m_quick_path;
        private string quick_path
        {
            get
            {
                if (m_quick_path == null)
                {
                    m_quick_path = Application.dataPath + "/../SDK/quickgame/Plugins";
                }
                return m_quick_path;
            }
            set { m_quick_path = value; }
        }
        /// <summary>
        /// 易盾SDK UI逻辑
        /// </summary>
        private void SetSDKSwitch()
        {
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("易盾SDK Path", GUILayout.Width(80f));
                YD_SDK_Path = EditorGUILayout.TextField(YD_SDK_Path);
                if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                {
                    BrowseYDPath("Select 易盾 Path", ref mYD_SDK_Path);
                }
                YD_Switch_Tag = EditorGUILayout.ToggleLeft("", YD_Switch_Tag, GUILayout.Width(12f));
                EditorGUI.BeginDisabledGroup(!YD_Switch_Tag);
                EditorGUILayout.LabelField("易盾反外挂", GUILayout.Width(60f));
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("bilibili", GUILayout.Width(80f));
                bilibili_path = EditorGUILayout.TextField(bilibili_path);
                if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                {
                    BrowseYDPath("Select bilibili Path", ref m_bilibili_path);
                }
                m_bilibili_tag = EditorGUILayout.ToggleLeft("", m_bilibili_tag, GUILayout.Width(12f));
                EditorGUI.BeginDisabledGroup(!m_bilibili_tag);
                EditorGUILayout.LabelField("bilibili", GUILayout.Width(60f));
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("数数SDK Path", GUILayout.Width(80f));
                shushu_path = EditorGUILayout.TextField(shushu_path);
                if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                {
                    BrowseYDPath("Select 数数 Path", ref m_shushu_path);
                }
                m_shushu_tag = EditorGUILayout.ToggleLeft("", m_shushu_tag, GUILayout.Width(12f));
                EditorGUI.BeginDisabledGroup(!m_shushu_tag);
                EditorGUILayout.LabelField("数数SDK", GUILayout.Width(60f));
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("热云SDK", GUILayout.Width(80f));
                reyun_path = EditorGUILayout.TextField(reyun_path);
                if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                {
                    BrowseYDPath("Select 热云 Path", ref m_reyun_path);
                }
                m_reyun_tag = EditorGUILayout.ToggleLeft("", m_reyun_tag, GUILayout.Width(12f));
                EditorGUI.BeginDisabledGroup(!m_reyun_tag);
                EditorGUILayout.LabelField("热云SDK", GUILayout.Width(60f));
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("QuickSDK", GUILayout.Width(80f));
                quick_path = EditorGUILayout.TextField(quick_path);
                if (GUILayout.Button("Browse...", GUILayout.Width(80f)))
                {
                    BrowseYDPath("Select Quick Path", ref m_quick_path);
                }
                m_quick_tag = EditorGUILayout.ToggleLeft("", m_quick_tag, GUILayout.Width(12f));
                EditorGUI.BeginDisabledGroup(!m_quick_tag);
                EditorGUILayout.LabelField("QuickSDK", GUILayout.Width(60f));
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndHorizontal();
        }
        private void BrowseYDPath(string titleStr, ref string path)
        {
            string directory = EditorUtility.OpenFolderPanel(titleStr, path, string.Empty);
            if (!string.IsNullOrEmpty(directory))
            {
                path = directory;
            }
        }
        private void RefreshYDFile()
        {
            if (Directory.Exists(YD_SDK_Path) == false)
            {
                Debug.LogError("易盾路径为空");
                return;
            }
            if (YD_Switch_Tag)
            {
                AddSDKFile2Plugins(YD_SDK_Path);
            }
            else
            {
                RemoveSDKFile2Plugins(YD_SDK_Path);
            }
        }

        private void RefreshBilibliFile(bool isDelete)
        {
            if (Directory.Exists(bilibili_path) == false)
            {
                Debug.LogError("bilibili路径为空");
                return;
            }
            if (isDelete)
            {
                RemoveSDKFile2Plugins(bilibili_path);
                return;
            }
            if (m_bilibili_tag)
            {
                m_Controller.SdkChannel = ResourceBuilderController.ESdkChannel.bilibili;
                AddSDKFile2Plugins(bilibili_path);
            }
        }

        private void RefreshShuShuSDKFile()
        {
            if (Directory.Exists(shushu_path) == false)
            {
                Debug.LogError("数数SDK路径为空");
                return;
            }
            if (m_shushu_tag)
            {
                AddAllSDKFile2Plugins(shushu_path);
            }
            else
            {
                RemoveAllSDKFile2Plugins(shushu_path);
            }
        }

        private void RefreshReYunFile(bool isDelete)
        {
            if (Directory.Exists(reyun_path) == false)
            {
                Debug.LogError("ReYun sdk 路径为空");
                return;
            }
            if (isDelete)
            {
                RemoveSDKFile2Plugins(reyun_path);
                return;
            }
            if (m_reyun_tag)
            {
                string skipFile = null;
                if (m_bilibili_tag || m_quick_tag)
                {
                    skipFile = "AndroidManifest.xml&oaid_sdk_1.2.1.aar";
                }
                AddSDKFile2Plugins(reyun_path, skipFile);
            }
        }

        private void RefreshQuickFile(bool isDelete)
        {
            if (Directory.Exists(quick_path) == false)
            {
                Debug.LogError("quick sdk 路径为空");
                return;
            }
            if (isDelete)
            {
                RemoveSDKFile2Plugins(quick_path);
                return;
            }
            if (m_quick_tag)
            {
                m_Controller.SdkChannel = ResourceBuilderController.ESdkChannel.quickgame;
                AddSDKFile2Plugins(quick_path);
            }
        }

        private void AddAllSDKFile2Plugins(string path)
        {
            DisposeAll2Target(path, Application.dataPath);
        }

        private void RemoveAllSDKFile2Plugins(string path)
        {
            DisposeAll2Target(path, Application.dataPath, true);
        }

        private void DisposeAll2Target(string fPath, string tPath, bool del = false)
        {
            string[] fDirList = Directory.GetDirectories(fPath);
            foreach (var fDir in fDirList)
            {
                string oFileName = Path.GetFileName(fDir);
                string tFilePath = tPath + "/" + oFileName;
                if (!Directory.Exists(tFilePath) && !del)
                {
                    Directory.CreateDirectory(tFilePath);
                }
                if (Directory.Exists(tFilePath))
                {
                    DisposeAll2Target(fDir, tFilePath, del);
                }
                if (Directory.Exists(tFilePath) && del && Directory.GetDirectories(tFilePath).Length <= 0 && Directory.GetFiles(tFilePath).Length <= 0)
                {
                    Debug.LogError($"删除空文件夹{tFilePath}");
                    Directory.Delete(tFilePath, true);
                }
            }
            var fFileList = Directory.GetFiles(fPath);
            var tFileList = Directory.GetFiles(tPath);
            foreach (var fFile in fFileList)
            {
                bool isExists = false;
                string fFileName = Path.GetFileName(fFile);
                foreach (var tFile in tFileList)
                {
                    string tFileName = Path.GetFileName(tFile);
                    if (tFileName.Equals(fFileName))
                    {
                        if (del)
                        {
                            Debug.LogError($"删除文件：{tFileName}");
                            File.Delete(tFile);
                        }
                        else
                        {
                            isExists = true;
                            break;
                        }
                    }
                }
                if (isExists == false)
                {
                    if (del == false)
                    {
                        Debug.LogError($"拷贝文件：{fFileName}");
                        string dest = Path.Combine(tPath, fFileName);
                        File.Copy(fFile, dest);
                    }
                }
            }
        }
        #endregion
        #endregion
    }
}
